package br.uefs.dexa.rfframework.gui.interfaces;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JPanel;

import br.uefs.dexa.rfframework.gui.impl.GPPlusRelevanceLevel;
import br.unicamp.ic.lis.rfframework.objects.DigitalObject;
import br.unicamp.ic.lis.rfframework.objects.DigitalObjectSet;
import br.unicamp.ic.lis.rfframework.objects.IDigitalObject;
import br.unicamp.ic.lis.rfframework.objects.LabeledDigitalObject;
import br.unicamp.ic.lis.rfframework.objects.exceptions.EmptyCollectionException;
import br.unicamp.ic.lis.rfframework.objects.exceptions.ObjectNotFoundException;

public abstract class ObjectSetContainerPanel extends JPanel implements RelevanceFeedbackViewer {

	
	private static final long serialVersionUID = 8980105710083510386L;
	

	protected DigitalObjectSet<LabeledDigitalObject> objects = new DigitalObjectSet<LabeledDigitalObject>();
	
	protected Map<Long, DigitalObjectPanel> panels = new HashMap<Long, DigitalObjectPanel>();
	
	private RFUserGUI gui;
	
	
	
	protected ObjectSetContainerPanel(RFUserGUI gui)
	{
		this.gui = gui;
		compose();
	}
	
	public Map<Long, DigitalObjectPanel> getPanels()
	{
		return Collections.unmodifiableMap(panels);
	}
	
	
	public void addObject(IDigitalObject object)
	{
		LabeledDigitalObject labeledObject = new LabeledDigitalObject((DigitalObject)object, (new GPPlusRelevanceLevel(GPPlusRelevanceLevel.RELEVANT)));
		DigitalObjectPanel panel = getDigitalObjectPanel(object);
		
		objects.addObject(labeledObject);
		panels.put(object.getId(), panel);
		showObjectPanel (panel);
		
		revalidate();
		repaint();
	}
	
	public void removeObject(IDigitalObject object)
	{
		try {
			objects.removeById(object.getId());
		} catch (ObjectNotFoundException e) {
			e.printStackTrace();
		} catch (EmptyCollectionException e) {
			e.printStackTrace();
		}
		
		removeObjectPanel (panels.get(new Long(object.getId())));
		panels.remove(object.getId());
		
		revalidate();
		repaint();
		
	}
	
	
		
	public DigitalObjectSet<LabeledDigitalObject> getObjects()
	{
		return this.objects;
	}
	
	public void clearObjects()
	{
		this.objects = new DigitalObjectSet<LabeledDigitalObject>();
	}
	
	public int getObjectsSize()
	{
		return this.objects.getSize();
	}

	protected RFUserGUI getGUI()
	{
		return this.gui;
	}
	
	public int getPanelsSize()
	{
		return panels.size();
	}
	
	

	/*
	 * Build panel components and layout. 
	 * Must be implemented on subclasses.
	 */
	public abstract void compose();	
	
	/*
	 * Displays the DigitalObjectPanel passed as argument on GUI.
	 * It usually just means to add the panel to some GUI container, like an internal JPanel.
	 * Must be implemented on subclasses. 
	 */
	public abstract void showObjectPanel(DigitalObjectPanel panel);
	
	/*
	 * Removes the DigitalObjectPanel passed as argument from GUI.
	 * It usually just means to remove the panel from it's GUI container, like an internal JPanel.
	 * Must be implemented on subclasses. 
	 */
	public abstract void removeObjectPanel(DigitalObjectPanel panel);
	
	/*
	 * Gets a new correspondent DigitalObjectPanel object to display the IDigitalObject passed as argument.
	 * It usually delegates the call to an appropriate factory.
	 * Must be implemented on subclasses. 
	 */
	public abstract DigitalObjectPanel getDigitalObjectPanel(IDigitalObject object);
	
	
	
	
	
	

}
